import { Callout } from "nextra/components";
import { Tabs } from 'nextra/components';
import { Widget } from '@/components/demo/widget.tsx';
import LinkBadge from '@/components/ui/link-badge/link-badge.tsx';
import LinkBadgeGroup from '@/components/ui/link-badge/link-badge-group.tsx';

# Text Form Field

A text field that can be used in forms, allowing the user to enter text, either with a hardware keyboard or with an
onscreen keyboard.

<LinkBadgeGroup>
    <LinkBadge label="API Reference" href="https://pub.dev/documentation/forui/latest/forui.widgets.text_field/"/>
</LinkBadgeGroup>

<Callout type="info">
  `FTextFormField` wraps [`FTextField`](/docs/form/text-field) and provides a
  [`FormField`](https://api.flutter.dev/flutter/widgets/FormField-class.html).
</Callout>

<Tabs items={['Preview', 'Code']}>
  <Tabs.Tab>
    <Widget name='text-form-field' height={550} query={{}}/>
  </Tabs.Tab>
  <Tabs.Tab>
    ```dart {9-11, 20-21, 27, 31-36, 38-42, 46-52} copy
    class LoginForm extends StatefulWidget {
      const LoginForm({super.key});

      @override
      State<LoginForm> createState() => _LoginFormState();
    }

    class _LoginFormState extends State<LoginForm> {
      final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
      final TextEditingController _emailController = TextEditingController();
      final TextEditingController _passwordController = TextEditingController();

      @override
      void initState() {
        super.initState();
      }

      @override
      void dispose() {
        _emailController.dispose();
        _passwordController.dispose();
        super.dispose();
      }

      @override
      Widget build(BuildContext context) => Form(
        key: _formKey,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            FTextFormField.email(
              controller: _emailController,
              hint: 'janedoe@foruslabs.com',
              autovalidateMode: AutovalidateMode.onUserInteraction,
              validator: (value) => (value?.contains('@') ?? false) ? null : 'Please enter a valid email.',
            ),
            const SizedBox(height: 10),
            FTextFormField.password(
              controller: _passwordController,
              autovalidateMode: AutovalidateMode.onUserInteraction,
              validator: (value) => 8 <= (value?.length ?? 0) ? null : 'Password must be at least 8 characters long.',
            ),
            const SizedBox(height: 20),
            FButton(
              child: const Text('Login'),
              onPress: () {
                if (!_formKey.currentState!.validate()) {
                  return; // Form is invalid.
                }

                // Form is valid, do something.
              },
            ),
          ],
        ),
      );
    }
    ```

  </Tabs.Tab>
</Tabs>

## CLI

To generate and customize this style:

```shell copy
dart run forui style create text-field
```

## Usage

### `FTextFormField(...)`

```dart copy
FTextFormField(
  controller: _controller, // TextEditingController
  style: FTextFieldStyle(...),
  clearable: (value) => value.text.isNotEmpty,
  enabled: true,
  onSaved: (value) {},
  onReset: () => print('Reset'),
  validator: (value) => true,
  label: const Text('Email'),
  hint: 'john@doe.com',
  description: const Text('Enter your email associated with your Forui account.'),
  forceErrorText: 'Error'
  errorBuilder: (context, error) => const Text(error),
  keyboardType: TextInputType.emailAddress,
  textCapitalization: TextCapitalization.none,
  maxLines: 1,
);
```

### `FTextFormField.email(...)`

```
FTextFormField.email(
  controller: _controller, // TextEditingController
  clearable: (value) => value.text.isNotEmpty,
  enabled: true,
  onSaved: (value) {},
  onReset: () => print('Reset'),
  validator: (value) => true,
  label: const Text('Email'),
  hint: 'john@doe.com',
  description: const Text('Enter your email associated with your Forui account.'),
  forceErrorText: 'Error'
  errorBuilder: (context, error) => const Text(error),
  keyboardType: TextInputType.emailAddress,
  textCapitalization: TextCapitalization.none,
  maxLines: 1,
);
```

### `FTextFormField.password(...)`

```dart copy
FTextFormField.password(
  controller: _controller, // TextEditingController
  clearable: (value) => value.text.isNotEmpty,
  enabled: true,
  onSaved: (value) {},
  onReset: () => print('Reset'),
  validator: (value) => true,
  label: const Text('Password'),
  hint: 'Enter password',
  description: const Text('Enter your password.'),
  forceErrorText: 'Error'
  errorBuilder: (context, error) => const Text(error),
  keyboardType: TextInputType.visiblePassword,
  textCapitalization: TextCapitalization.none,
  maxLines: 1,
  obscureTextController: ValueNotifier(false),
);
```

### `FTextFormField.multiline(...)`

```dart copy
FTextFormField.multiline(
  controller: _controller, // TextEditingController
  clearable: (value) => value.text.isNotEmpty,
  enabled: true,
  onSaved: (value) {},
  onReset: () => print('Reset'),
  validator: (value) => true,
  label: const Text('Description'),
  hint: 'Enter description',
  description: const Text('Enter your description.'),
  forceErrorText: 'Error'
  errorBuilder: (context, error) => const Text(error),
  keyboardType: TextInputType.multiline,
  textCapitalization: TextCapitalization.none,
  maxLines: null,
);
```
